#    This file is part of robo-ircbot.
#
#    robo-ircbot is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    robo-ircbot is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with robo-ircbot.  If not, see <http://www.gnu.org/licenses/>.

package Robo::IRC;
use strict;
use warnings;
use IO::Socket;
use IO::Socket::SSL;
use Robo::EventHandler;

# Constructor
sub new
{
        my ($class, $robo, $cfg, $mod) = @_;
        
        my $self = { };
        
        $self->{robo} = $robo;
        $self->{cfg} = $cfg;
        $self->{mod} = $mod;
        $self->{sock} = undef;
        $self->{event} = undef;
        
        bless($self);
        return $self;
}

# Connect to IRC server.
sub irc_connect
{
        my $self = shift;
        
        # Infinite connection loop.
        while (1) {
                $self->{robo}->log(":: Connecting to ".
                                   $self->{cfg}->get_cfg("server/address").":".
                                   $self->{cfg}->get_cfg("server/port"));
                
                # Create main socket using SSL.
                if ($self->{cfg}->get_cfg("server/use_ssl") eq "yes") {
                        $self->{sock} = IO::Socket::SSL->new(
                                PeerAddr => $self->{cfg}->get_cfg("server/address"),
                                PeerPort => $self->{cfg}->get_cfg("server/port"),
                                Proto    => "tcp"
                        );
                
                # Create normal socket.
                } else {
                        $self->{sock} = IO::Socket::INET->new(
                                PeerAddr => $self->{cfg}->get_cfg("server/address"),
                                PeerPort => $self->{cfg}->get_cfg("server/port"),
                                Proto    => "tcp"
                        );
                }
                
                # If we could not connect to the server, retry after
                # configured amount of seconds.
                if (!$self->{sock}) {
                        $self->{robo}->log(":: Could not connect, retrying in ".
                                           $self->{cfg}->get_cfg("server/retry_delay").
                                           " seconds.");
                        sleep($self->{cfg}->get_cfg("server/retry_delay"));
                        next;
                }
                
                # Send user information to start connection.
                print {$self->{sock}} "NICK ".$self->{cfg}->get_cfg("bot/nick").
                                      "\r\nUSER ".$self->{cfg}->get_cfg("bot/user_name").
                                      " 0 0 :".$self->{cfg}->get_cfg("bot/real_name")."\r\n";
                
                # Start the Listener.
                if (!$self->{robo}->{listener}) {
                        $self->{robo}->{listener} = Robo::Listener->new($self->{robo},
                                                                        $self->{cfg},
                                                                        $self->{mod},
                                                                        $self->{sock});
                        $self->{robo}->{listener}->start_listening();
                } else {
                        $self->{robo}->{listener}->{irc_sock} = $self->{sock};
                        $self->{robo}->reload();
                }
                
                # Start the event loop.
                $self->{event} = Robo::EventHandler->new($self->{robo},
                                                         $self->{cfg},
                                                         $self->{sock},
                                                         $self->{mod});
                
                $self->{robo}->log(":: Starting event handler.");
                $self->{event}->event_loop();
                
                # Close the socket.
                if ($self->{sock}) {
                        close($self->{sock});
                }
        }
}

1;
